home *** CD-ROM | disk | FTP | other *** search
- /*
- File: KeyboardDiagram.c
-
- Modified version from the one in the warhol project
-
- */
-
-
- #include <Memory.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include "IE KeyboardDiagram.h"
-
- static Handle GetAndDetachResource(ResType type,short id);
-
- #define kBlackKeyBottom 16
-
- static Handle GetAndDetachResource(ResType type,short id)
- {
- Handle h;
-
- h = GetResource(type,id);
- DetachResource(h);
- return h;
- }
-
- void InitializeKeyboard(KeyboardDiagram *kd,Rect *r,short octaveCount,short lowKey)
- {
- short i;
-
- kd->r = *r;
- kd->octaveCount = octaveCount;
- kd->keyCount = octaveCount * 12;
-
- if(lowKey >= 128)
- {
- kd->mod = true;
- kd->modOffset = ((lowKey + kd->keyCount - 1) / kd->keyCount) * kd->keyCount;
- lowKey &= 127;
- }
- else
- kd->mod = false;
-
- kd->lowKey = lowKey;
-
- for(i = 0; i < 128; i++)
- kd->keyVel[i] = 0;
-
- kd->whiteKey = (short **)GetAndDetachResource('Junk',kJunkWhite);
- kd->keyRight = (short **)GetAndDetachResource('Junk',kJunkBlack);
- }
-
- void TerminateKeyboard(KeyboardDiagram *kd)
- {
- DisposeHandle((Handle)kd->whiteKey);
- DisposeHandle((Handle)kd->keyRight);
- }
-
- void SetKeyboardTopLeft(KeyboardDiagram *kd,short top, short left)
- {
- OffsetRect(&kd->r, left - kd->r.left, top - kd->r.top);
- }
-
- void DrawKeyboardPiece(KeyboardDiagram *kd, short octave)
- {
- Rect r;
- short w;
- PicHandle pH;
-
- PenNormal();
-
- pH = (PicHandle)Get1Resource('PICT',kKeyboardPict);
- if(pH)
- {
- r = (**pH).picFrame;
- w = r.right - r.left-1;
- OffsetRect(&r,kd->r.left - r.left + w * octave,kd->r.top - r.top);
- DrawPicture(pH,&r);
-
- if(kd->gray)
- {
- GoGray();
- PenMode(patBic);
- r.right += 2;
- r.bottom += 2;
- PaintRect(&r);
- PenNormal();
- }
- }
- }
-
-
- void DrawKeyboardDropShadow(KeyboardDiagram *kd)
- {
- MoveTo(kd->r.left + 3,kd->r.bottom);
- LineTo(kd->r.right,kd->r.bottom);
- LineTo(kd->r.right,kd->r.top + 3);
- }
-
- void DrawKeyboard(KeyboardDiagram *kd)
- {
- short i;
-
- DrawKeyboardDropShadow(kd);
- for(i = 0; i < kd->octaveCount; i++)
- DrawKeyboardPiece(kd,i);
- }
-
- void SetKeyboardGray(KeyboardDiagram *kd,Boolean gray)
- {
- if(kd->gray != gray)
- {
- kd->gray = gray;
- DrawKeyboard(kd);
- }
- }
-
-
-
- void PaintKeyboardKey(KeyboardDiagram *kd,short pitch,short gray)
- /*
- * 0-255, gray; -1, invert; -2, forecolor
- */
- {
- short i,k;
- short octave;
- Rect r1,r2;
- Boolean blackKey;
-
- if(kd->gray)
- goto goHome;
-
-
- r1.left = r1.right = 0;
- r2.left = r2.right = 0;
-
- pitch -= kd->lowKey;
- if(pitch < 0 || pitch >= kd->keyCount)
- goto goHome;
-
- octave = pitch / 12;
- pitch = pitch % 12;
-
- blackKey = false;
-
- if(pitch == 1 || pitch == 3
- || pitch == 6 || pitch == 8 || pitch == 10)
- {
- /*
- * Black Keys
- */
- blackKey = true;
- r1.left = kd->r.left + (*kd->keyRight)[pitch - 1] + 2;
- r1.top = kd->r.top + 3;
- r1.right = kd->r.left + (*kd->keyRight)[pitch];
- r1.bottom = kd->r.top + kBlackKeyBottom;
- }
- else
- {
- /*
- * White Keys
- */
- k = kd->r.left + 2;
- i = 0;
- while((*kd->whiteKey)[i] != pitch)
- {
- i++;
- k += 9;
- }
- r1.left = k;
- r1.top = kd->r.top + kBlackKeyBottom + 2;
- r1.right = k+6;
- r1.bottom = kd->r.bottom - 1;
-
- if(pitch)
- r2.left = kd->r.left + (*kd->keyRight)[pitch - 1] + 2;
- else
- r2.left = kd->r.left + 2;
- r2.top = kd->r.top + 2;
- r2.right = kd->r.left + (*kd->keyRight)[pitch];
- r2.bottom = kd->r.top + kBlackKeyBottom + 2;
-
- /*
- * This is cheesy and proves I have
- * no idea what I am doing. - dvb
- */
- if(pitch == 5)
- r2.left ++;
- else if(pitch == 11)
- r2.right --;
- }
-
- OffsetRect(&r1,octave * 63,0);
- OffsetRect(&r2,octave * 63,0);
-
- if(gray >=0)
- {
- RGBColor c;
-
- if(!blackKey)
- gray = 255 - gray;
- c.blue = c.green = c.red = (((unsigned short)gray)<<8) | gray;
- RGBForeColor(&c);
- }
-
- if(gray == -1)
- {
- InvertRect(&r1);
- InvertRect(&r2);
- }
- else
- {
- PaintRect(&r1);
- PaintRect(&r2);
- }
- goHome:
- ForeColor(blackColor);
- PenNormal();
- }
-
-
- void PaintKeyboardVector(KeyboardDiagram *kd,unsigned char *keyVel)
- {
- short i;
- unsigned char *w1,*w2;
- long x;
-
- w1 = keyVel;
- w2 = kd->keyVel;
- for(i = 0; i < 128; i++)
- {
- x = *w1;
- if(*w2 != x)
- {
- *w2 = x;
- x = x ? x+128:0;
- if( (i < kd->lowKey) || (i >= (kd->lowKey + kd->keyCount)) )
- {
- if(kd->mod)
- PaintKeyboardKey(kd,
- (i+kd->modOffset)%(kd->keyCount)+kd->lowKey,x);
- }
- PaintKeyboardKey(kd,i,x);
- }
- w1++;
- w2++;
- }
- }
-
-
- short GetKeyboardKey(KeyboardDiagram *kd,Point p)
- /*
- * Return -1 if outside rectangle.
- */
- {
- short pitch,octave;
-
- if(PtInRect(p,&kd->r))
- {
- p.h -= kd->r.left;
- p.v -= kd->r.top;
-
- octave = p.h / 63;
- p.h %= 63;
-
- if(p.v > kBlackKeyBottom)
- pitch = (*kd->whiteKey)[p.h/9];
- else
- {
- pitch = 0;
- while((*kd->keyRight)[pitch] < p.h)
- pitch++;
- }
- pitch += octave*12;
- pitch += kd->lowKey;
- }
- else
- pitch = -1;
-
- return pitch;
- }
-
-